Makefile patch.
[XEND] Remove blank image file generation for QCOW images.
There is no need for a blank backing store, although this means we
have to find a new way to determine how much virtual disk space is
free in the StorageRepository.
Beginnings to attempt to supoprt HVM guests.
Signed-off-by: Alastair Tse <atse@xensource.com>
'vm-shutdown': [(('-f', '--force'), {'help': 'Shutdown Forcefully',
'action': 'store_true'})],
- 'vdi-create': [(('--label',), {'help': 'Name for VDI'}),
+ 'vdi-create': [(('--name-label',), {'help': 'Name for VDI'}),
(('--description',), {'help': 'Description for VDI'}),
(('--sector-size',), {'type': 'int',
'help': 'Sector size'}),
raise OptionError("Configuration file and domain not specified")
domname = args[0]
- filename = args[1]
- cfg = _read_python_cfg(filename)
+ if len(args) > 1:
+ filename = args[1]
+ cfg = _read_python_cfg(filename)
+ else:
+ cfg = {}
+
for opt, val in opts:
cfg[opt] = val
- print 'Creating VBD from %s ..' % filename
+ print 'Creating VBD ...',
server, session = _connect()
vm_uuid = resolve_vm(server, session, domname)
cfg['VM'] = vm_uuid
def xapi_vdi_create(*args):
opts, args = parse_args('vdi-create', args)
- if len(args) < 1:
- raise OptionError("Not enough arguments.")
-
- cfg = _read_python_cfg(args[0])
+ if len(args) > 0:
+ cfg = _read_python_cfg(args[0])
+ else:
+ cfg = {}
+
for opt, val in opts:
cfg[opt] = val
cfg['SR'] = sr
size = (cfg['virtual_size'] * cfg['sector_size'])/MB
- print 'Creating VDI of size: %dMB' % size
+ print 'Creating VDI of size: %dMB ..' % size,
uuid = execute(server.VDI.create, session, cfg)
print 'Done. (%s)' % uuid
# Command Line Utils
#
import cmd
+import shlex
+
class XenAPICmd(cmd.Cmd):
def __init__(self, server, session):
cmd.Cmd.__init__(self)
self.prompt = ">>> "
def default(self, line):
- words = line.split()
+ words = shlex.split(line)
if len(words) > 0:
cmd_name = words[0].replace('-', '_')
func_name = 'xapi_%s' % cmd_name
def do_help(self, line):
usage(print_usage = False)
+ def emptyline(self):
+ pass
+
def postcmd(self, stop, line):
return False
def precmd(self, line):
- words = line.split()
+ words = shlex.split(line)
if len(words) > 0:
words0 = words[0].replace('-', '_')
return ' '.join([words0] + words[1:])
def vbd_get_vm(self, session, vbd_ref):
xendom = XendDomain.instance()
return xen_api_success(xendom.get_dev_property('vbd', vbd_ref, 'VM'))
+
def vbd_get_vdi(self, session, vbd_ref):
- return xen_api_error(XEND_ERROR_UNSUPPORTED)
+ return xen_api_todo()
+
def vbd_get_device(self, session, vbd_ref):
xendom = XendDomain.instance()
return xen_api_success(xendom.get_dev_property('vbd', vbd_ref,
'vbds',
]
+XENAPI_HVM_CFG = {
+ 'platform_std_vga': 'std-vga',
+ 'platform_serial' : 'serial',
+ 'platform_localtime': 'localtime',
+ 'platform_enable_audio': 'soundhw',
+}
+
XENAPI_UNSUPPORTED_IN_LEGACY_CFG = [
'name_description',
'user_version',
'otherconfig'
]
+
# configuration params that need to be converted to ints
# since the XMLRPC transport for Xen API does not use
# 32 bit ints but string representation of 64 bit ints.
raise XendConfigError('integer expeceted: %s: %s' %
str(cfg['image']), e)
-
# Deprecated cpu configuration
if 'cpu' in cfg:
if 'cpus' in cfg:
sxp_image.append(['ramdisk', xenapi_vm['kernel_initrd']])
if xenapi_vm['kernel_args']:
sxp_image.append(['args', xenapi_vm['kernel_args']])
+
cfg['image'] = prettyprintstring(sxp_image)
# make sure device structures are there.
try:
try:
dom0info = [d for d in self._running_domains() \
- if d['domid'] == DOM0_ID][0]
+ if d.get('domid') == DOM0_ID][0]
dom0info['name'] = DOM0_NAME
dom0 = XendDomainInfo.recreate(dom0info, True)
XEND_STORAGE_MAX_IGNORE = -1
XEND_STORAGE_DIR = "/var/lib/xend/storage/"
XEND_STORAGE_QCOW_FILENAME = "%s.qcow"
-XEND_STORAGE_IMG_FILENAME = "%s.img"
XEND_STORAGE_VDICFG_FILENAME = "%s.vdi.xml"
DF_COMMAND = "df -lPk"
-QCOW_CREATE_COMMAND = "/usr/sbin/qcow-create %d %s %s"
+QCOW_CREATE_COMMAND = "/usr/sbin/qcow-create %d %s"
KB = 1024
MB = 1024 *1024
image_uuid = filename[:-5]
seen_images.append(image_uuid)
if image_uuid not in self.images:
- image_file = XEND_STORAGE_IMG_FILENAME % image_uuid
qcow_file = XEND_STORAGE_QCOW_FILENAME % image_uuid
cfg_file = XEND_STORAGE_VDICFG_FILENAME % image_uuid
-
- image_path = os.path.join(XEND_STORAGE_DIR,image_file)
qcow_path = os.path.join(XEND_STORAGE_DIR, qcow_file)
cfg_path = os.path.join(XEND_STORAGE_DIR, cfg_file)
qcow_size = os.stat(qcow_path).st_size
- image_size = os.stat(image_path).st_size
+ # TODO: no way to stat virtual size of qcow
vdi = XendQCOWVDI(image_uuid, self.uuid,
- qcow_path, image_path, cfg_path,
- image_size,
- qcow_size + image_size)
+ qcow_path, cfg_path,
+ qcow_size, qcow_size)
if cfg_path and os.path.exists(cfg_path):
vdi.load_config(cfg_path)
self.images[image_uuid] = vdi
- total_used += image_size
+ total_used += qcow_size
# remove images that aren't valid
for image_uuid in self.images.keys():
if image_uuid not in seen_images:
try:
os.unlink(self.images[image_uuid].qcow_path)
- os.unlink(self.images[image_uuid].image_path)
except OSError:
pass
del self.images[image_uuid]
raise XendError("Not enough space")
image_uuid = uuid.createString()
- # create file based image
- image_path = os.path.join(XEND_STORAGE_DIR,
- XEND_STORAGE_IMG_FILENAME % image_uuid)
+ qcow_path = os.path.join(XEND_STORAGE_DIR,
+ XEND_STORAGE_QCOW_FILENAME % image_uuid)
- if image_path and os.path.exists(image_path):
+ if qcow_path and os.path.exists(qcow_path):
raise XendError("Image with same UUID alreaady exists:" %
image_uuid)
- block = '\x00' * KB
- img = open(image_path, 'w')
- for i in range(desired_size_bytes/KB):
- img.write(block)
- img.close()
-
- # TODO: create qcow image
- qcow_path = os.path.join(XEND_STORAGE_DIR,
- XEND_STORAGE_QCOW_FILENAME % image_uuid)
- cmd = QCOW_CREATE_COMMAND % (desired_size_bytes/MB,
- qcow_path, image_path)
-
+ cmd = QCOW_CREATE_COMMAND % (desired_size_bytes/MB, qcow_path)
rc, output = commands.getstatusoutput(cmd)
+
if rc != 0:
# cleanup the image file
- os.unlink(image_path)
+ os.unlink(qcow_path)
raise XendError("Failed to create QCOW Image: %s" % output)
self._refresh()
if image_uuid in self.images:
# TODO: check if it is being used?
qcow_path = self.images[image_uuid].qcow_path
- image_path = self.images[image_uuid].image_path
cfg_path = self.images[image_uuid].cfg_path
try:
os.unlink(qcow_path)
- os.unlink(image_path)
if cfg_path and os.path.exists(cfg_path):
os.unlink(cfg_path)
except OSError:
class XendQCOWVDI(XendVDI):
- def __init__(self, uuid, sr_uuid, qcow_path, image_path, cfg_path,
- vsize, psize):
+ def __init__(self, uuid, sr_uuid, qcow_path, cfg_path, vsize, psize):
XendVDI.__init__(self, uuid, sr_uuid)
self.auto_save = False
self.qcow_path = qcow_path
- self.image_path = image_path
self.cfg_path = cfg_path
self.physical_utilisation = psize
self.virtual_size = vsize
- self.sector_size = 1
+ self.sector_size = 512
self.auto_save = True